#ifndef NANE_INPUTSYSTEM_H
#   define  NANE_INPUTSYSTEM_H

#   include "nane/InputSystem/InputDeviceSystem.h"
#   include "nane/InputSystem/InputAxis.h"

namespace nane
{
    struct InputBindingModifier
    {
        EInputDevice deviceType;
        byte deviceNum;
        byte axis;
        
        InputBindingModifier( EInputDevice _deviceType, byte _deviceNum, byte _axis )
            : deviceType( _deviceType )
            , deviceNum( _deviceNum )
            , axis( _axis )
        {
        }
        
        InputBindingModifier( EKeyCode _keyCode )
            : deviceType( EInputDevice::Keyboard )
            , deviceNum( 0 )
            , axis( _keyCode.raw_value() )
        {
        }
        
        InputBindingModifier( EMouseAxis _mouseAxis )
            : deviceType( EInputDevice::Mouse )
            , deviceNum( 0 )
            , axis( _mouseAxis.raw_value() )
        {
        }
    };
        
    struct InputBinding
        : public InputBindingModifier
    {
        float scale;
        float treshold;
        
        InputBinding( EKeyCode _keyCode, float _scale = 1.0f, float _treshold = 0.0f )
            : InputBindingModifier( _keyCode )
            , scale( _scale )
            , treshold( _treshold )
        {
        }
        
        InputBinding( EMouseAxis _mouseAxis, float _scale = 1.0f, float _treshold = 0.0f )
            : InputBindingModifier( _mouseAxis )
            , scale( _scale )
            , treshold( _treshold )
        {
        }
    };
    
    class InputSystem
    {
    public:
        InputSystem();
        ~InputSystem();
        
    public:
        bool Initialize( IWindow::OSHandle _windowHandle );
        void Shutdown();
        bool AddInputDevice( InputDeviceSystem* _inputDeviceSystem );
        void RemoveInputDevice( InputDeviceSystem* _inputDeviceSystem );
        void Update();
        void AddActionBinding( const char* _action, const InputBinding& _inputBinding );
        void AddActionBinding( const char* _action, const InputBinding& _inputBinding, const InputBindingModifier& _modifier );
        void AddActionBinding( const char* _action, const InputBinding& _inputBinding, const InputBindingModifier& _modifier1, const InputBindingModifier& _modifier2 );
        void RemoveActionBinding( const char* _action, const InputBinding& _inputBinding );
        float GetActionValue( const char* _action );
        bool GetActionIsPressed( const char* _action );
        uint32 GetActionWasPressed( const char* _action );
        bool GetActionIsReleased( const char* _action );
        uint32 GetActionWasReleased( const char* _action );
        
    private:
        class Implementation;
        Implementation* m;
    };
}   // namespace nane

#endif	// NANE_INPUTSYSTEM_H
